package cn.ad.server.web.spring.service.biz;

import cn.ad.server.web.spring.model.AdImpression;
import cn.ad.server.web.spring.model.AdNative;
import cn.ad.server.web.spring.model.Exchange;
import cn.ad.server.web.spring.model.bes.AdslotType;
import cn.ad.server.web.spring.model.bes.BES;
import cn.ad.server.web.spring.model.bes.BES.BidRequest.AdSlot;
import cn.ad.server.web.spring.model.bes.BES.BidResponse.Ad;
import cn.ad.server.web.spring.model.bes.BES.BidResponse.Ad.Builder;
import cn.ad.server.web.spring.service.actions.context.BidContext;
import cn.ad.server.biz.internal.AdService;
import cn.ad.server.domain.ad.AdSpace;
import cn.ad.server.domain.ad.AdTemplate;
import cn.ad.server.domain.ad.Strategy;
import cn.ad.server.domain.enumration.AdFormat;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.Set;

@Component
public class BESImpressionMatchService extends ImpressionMatchService<Ad.Builder> {

	private static final int BES_DEFAULT_CHANNEL = 10;
	private static final int BES_DEFAULT_PLATFORM = 6;

	private static Logger LOGGER = LoggerFactory.getLogger(BESImpressionMatchService.class);

	@Autowired
	private AdService adService;

	@Autowired
	private TrackingService trackingService;


	@Override
	public Exchange getExchange() {
		return Exchange.BES;
	}

//<<<<<<< HEAD

	public Ad.Builder handler(AdSlot impression, BidContext bidContext) {
		
		// 取得现在的广告形式
				AdSlot adViewImpression = impression;
				AdslotType type = convert(impression.getAdslotType());
				AdFormat adFormat = convert(type);
				// 区别原生和非原生
				// 策略列表
				Set<Strategy> strategyList = null;
				AdTemplate adTemplate = null;
				boolean serverFilter = false;
				int platformId = 0;
				// long adSpaceId = 0;
				AdSpace localAdSpace = null;
				if (adFormat != AdFormat.AD_NATIVE&&adFormat != AdFormat.UNKOWN) {
					strategyList = adService.fetchPlatformById(Integer.parseInt(Exchange.BES.getValue())).getStrategies();
				} else {
					//其他不支持
					return null;
				}

				if (strategyList == null)
					return null;
//				bidContext.setImpId(String.valueOf(adViewImpression.getAdBlockKey()));
				bidContext.setAdxSpaceId(String.valueOf(adViewImpression.getAdBlockKey()));
				bidContext.setBidFloor(
						new BigDecimal(adViewImpression.getMinimumCpm()).divide(new BigDecimal(100)).doubleValue());
				//bidContext.setPriceUnit("fen");//TODO bes默认为 分。
				bidContext.setAdReqFormat(impression.getAdslotType());
				bidContext.setAdFormat(adFormat.getValue());
				bidContext.setAdxTagId(null);

				int width = adViewImpression.getWidth();
				int height = adViewImpression.getHeight();

				bidContext.setAdspaceWidth(String.valueOf(width));
				bidContext.setAdspaceHeight(String.valueOf(height));
				
				bidContext.setScreenPosition(String.valueOf(adViewImpression.getSlotVisibility()));
				
//				bidContext.setExcludeCreativeType();
				bidContext.setIncludeCreativeType(adViewImpression.getCreativeTypeList());
				
				//excluded_product_category 发布商不允许的广告行业 TODO
				
				//发布商不允许的landing page url TODO
				
				Ad.Builder ad = (Ad.Builder) strategyFilter(strategyList, bidContext, adTemplate, null, width, height,
						serverFilter, platformId, localAdSpace);
				//TODO ...
				
				 return ad;
//=======
//	public Ad handler(AdSlot impression, BidContext bidContext) {
//
//		// 取得现在的广告形式
//		AdSlot adViewImpression = impression;
//		AdslotType type = convert(impression.getAdslotType());
//		AdFormat adFormat = convert(type);
//		// 区别原生和非原生
//		// 策略列表
//		Set<Strategy> strategyList = null;
//		AdTemplate adTemplate = null;
//		boolean serverFilter = false;
//		int platformId = 0;
//		// long adSpaceId = 0;
//		AdSpace localAdSpace = null;
//		if (adFormat != AdFormat.AD_NATIVE) {
//			strategyList = adService.fetchPlatformById(Integer.parseInt(Exchange.ADVIEW.getValue())).getStrategies();
//		} else {
//			// 不支持原生。
//			return null;
//		}
//
//		if (strategyList == null)
//			return null;
//		bidContext.setImpId(String.valueOf(adViewImpression.getAdBlockKey()));
//		bidContext.setBidFloor(
//				new BigDecimal(adViewImpression.getMinimumCpm()).divide(new BigDecimal(10000)).doubleValue());
//		bidContext.setPriceUnit("fen");// TODO 默认为 分。
//		bidContext.setAdFormat(adFormat.getValue());
//		bidContext.setAdxTagId(null);
//
//		if (adFormat == AdFormat.AD_NATIVE && adTemplate == null)
//			return null;
//
//		int width = adViewImpression.getWidth();
//		int height = adViewImpression.getHeight();
//
//		bidContext.setAdspaceWidth(String.valueOf(width));
//		bidContext.setAdspaceHeight(String.valueOf(height));
//
//		bidContext.setScreenPosition(String.valueOf(adViewImpression.getSlotVisibility()));
//
//		// bidContext.setExcludeCreativeType(StringUtil.arrayToCommaDelimitedString(adViewImpression.getCreativeTypeList()));
//
//		Ad ad = (Ad) strategyFilter(strategyList, bidContext, adTemplate, null, width, height, serverFilter, platformId,
//				localAdSpace);
//		// TODO ...
//
//		return ad;
//>>>>>>> develop
	}

	@Override
	public Ad.Builder handler(AdImpression impression, BidContext bidContext) {
		return null;
	}

	public AdFormat convert(AdslotType type) {
		if(type==null){
			return AdFormat.UNKOWN;
		}
		int adformatVal = type.getAdformatVal();
		return AdFormat.adFormatMap.get(adformatVal);
	}

	public AdslotType convert(int value) {
		return AdslotType.typeMap.get(value);
	}
//<<<<<<< HEAD
	

	@Override
	public Ad.Builder compositeBid(BidContext bidContext, Entry entry) {
		Object OriginImpression = bidContext.getOriginImpression();
		AdSlot adSlot = null;
		if(OriginImpression instanceof AdSlot){
			adSlot = (AdSlot)OriginImpression;
		}
//=======
//
//	Set<Strategy> matchUserDmp(BidContext bidContext, Set<Strategy> strategySet) {
//		Set<Strategy> resultSet = new HashSet<Strategy>();
//		// resultSet.addAll(strategySet);
//
//		for (Strategy s : strategySet) {
//			List<String> dmpIds = adService.fetchUserDmpId(s.getId(), Integer.valueOf(bidContext.getChannel()));
//			if (CollectionUtils.isEmpty(dmpIds)) {
//				resultSet.add(s);
//				continue;
//			}
//
//			if (CollectionUtils.isEmpty(bidContext.getUserDmpId())) {
//				// MonitorHandler.monitorStrategy(configRepository.fetchMonitoredStrategy(),
//				// configRepository.fetchDebugMode(), Strategy.class.getName(),
//				// String.valueOf(s.getId()),
//				// "input audience_ids is null");
//
//				// LOGGER.info("input audience_ids is null:{},{}", s.getId(),
//				// bidContext.getUserDmpId());
//				// resultSet.remove(s);
//				continue;
//			}
//
//			Set<Integer> userDmpSet = new HashSet<Integer>();
//			for (String ud : dmpIds) {
//				userDmpSet.add(Integer.valueOf(ud));
//			}
//			Set<Integer> result = new HashSet<Integer>();
//			result.addAll(userDmpSet);
//			result.retainAll(new HashSet<Integer>(bidContext.getUserDmpId()));
//			if (result.size() == 0) {
//				// LOGGER.info("audience_ids is not match is not
//				// match:{},{},{}", s.getId(), dmpIds,
//				// bidContext.getUserDmpId());
//				MonitorHandler.monitorStrategy(configRepository.fetchMonitoredStrategy(),
//						configRepository.fetchDebugMode(), Strategy.class.getName(), String.valueOf(s.getId()),
//						"audience_ids is not match");
//				// resultSet.remove(s);
//			} else if (result.size() > 0) {
//				resultSet.add(s);
//			}
//		}
//		return resultSet;
//	}
//
//	@Override
//	public Ad compositeBid(BidContext bidContext, Entry entry) {
//		Object originReq = bidContext.getOriginReq();
//		// if(originReq instanceof ){
//		//
//		// }
//>>>>>>> develop
		Builder adBuilder = BES.BidResponse.Ad.newBuilder();
		adBuilder.setSequenceId(adSlot.getSequenceId());
		adBuilder.setCreativeId(bidContext.getCreativeId());
//<<<<<<< HEAD
		
//		adBuilder.setHtmlSnippet(value)//仅动态创意需要填充
//		adBuilder.setLinkUnitKeyword(value)//竞价链接单元广告的关键词
//		adBuilder.setExpandCreativeInfo(value)//目前BES对扩展创意的支持仅限于动态创意，亦即填充了html_snippet。
//		adBuilder.setAdvertiserId(value)// 广告主id。动态创意及关键词需要填充
//		adBuilder.setWidth(value)//// 仅动态创意需要填充
//		adBuilder.setHeight(value)//// 仅动态创意需要填充
//		adBuilder.setCategory(value)// 动态创意和关键词需要填充
//		adBuilder.setType(value);//动态创意和关键词需要填充
//		adBuilder.setLandingPage(value);//动态创意和关键词需要填充
//		adBuilder.setTargetUrl(index, value);//动态创意和关键词需要填充
//		adBuilder.setMonitorUrls(index, value);//动态创意和关键词需要填充
		adBuilder.setMaxCpm(entry.getPrice().multiply(new BigDecimal(100)).intValue());//最高竞价，单位分
//		//TODO TEST
//		if(entry.getPrice().doubleValue()==0.2d){
//			adBuilder.setMaxCpm(10000);
//		}
		
		String impressionParam = compositeImpUrls(bidContext, entry);
		String impressionParam_code = "";
		try {
			impressionParam_code = Base64.encodeBase64String(impressionParam.getBytes());
		} catch (Exception e) {
			e.printStackTrace();
		}
		adBuilder.setExtdata(impressionParam_code);//扩展参数
		
//		adBuilder.setIsCookieMatching(false)//是否进行cookie mapping
//		adBuilder.setPreferredOrderId(value)//如果采用优先交易，该交易的ID
//		adBuilder.setGuaranteedOrderId(value)//如果采用包断投放，投放的id
		//adBuilder.setDeeplinkInfo(null);//APP 唤醒信息
//=======
//		adBuilder.setSequenceId(0);
//		// adBuilder.setType(value);//动态创意和关键词需要填充
//		// adBuilder.setLandingPage(value);
//		// adBuilder.setTargetUrl(index, value);
//		// adBuilder.setMonitorUrls(index, value);
//		// adBuilder.setMaxCpm(value);
//		// adBuilder.setDeeplinkInfo(null);
//
//		// 如果是动态创意。
//
//		// Ad bid = BES.BidResponse.Ad.newBuilder()
//		// bid.newBuilder()
//		// BES.BidResponse.Ad.newBuilder().getCreativeId();
//		// BES.BidResponse.Ad.newBuilder().getHtmlSnippet()
//		// BES.BidResponse.Ad.newBuilder().setCreativeId(value)
//
//		// double bidAdViewRatio =
//		// adService.getRatio(bidContext.getCampaignId());
//		// bid.setBid_price(entry.getPrice().multiply(new BigDecimal(100 *
//		// bidAdViewRatio)).intValue());
//		// bid.setCreative_id(entry.getAuditId());
//		// String impressionParam = compositeImpUrls(bidContext, entry);
//		// String clickParam = compositeClickUrl(bidContext, entry);
//		//
//		// String clickParam_code = "";
//		// String impressionParam_code = "";
//		//
//		// try {
//		// // 移动联盟是base64，其他的是urlencode
//		// if (ckechMobileUnion(bidContext.getCreativeSpec())) {
//		// clickParam_code = Base64.encodeBase64String(clickParam.getBytes());
//		// impressionParam_code =
//		// Base64.encodeBase64String(impressionParam.getBytes());
//		// } else {
//		// clickParam_code = URLEncoder.encode(clickParam, "UTF-8");
//		// impressionParam_code = URLEncoder.encode(impressionParam, "UTF-8");
//		// }
//		//
//		// } catch (Exception e) {
//		// e.printStackTrace();
//		// }
//		//
//		// bid.setClick_param(clickParam_code);
//		// bid.setImpression_param(impressionParam_code);
//		// bid.setStrategy_priority(entry.getPriority());
//>>>>>>> develop

		return adBuilder;
	}


	@Override
	public void storeTemplateSpec(Entry entry, AdNative adNative) {

	}

	/**
	 * 组合印象数据
	 * 
	 * @param bidContext
	 * @param entry
	 * @return
	 */
	protected String compositeImpUrls(BidContext bidContext, Entry entry) {
		return trackingService.buildImpressionQueryString("2.0", NumberUtils.toInt(bidContext.getChannel(), BES_DEFAULT_CHANNEL), BES_DEFAULT_PLATFORM, 0,
				bidContext.getStrategyId(), bidContext.getCreativeId(), bidContext.getMaterialId(),
				bidContext.getGuid(), bidContext.getOs());
	}

	/**
	 * 组合点击数据
	 *
	 * @param bidContext
	 * @return
	 */
	protected String compositeClickUrl(BidContext bidContext, Entry entry) {
		String targetUrl = null;
		try {
			targetUrl = URLEncoder.encode(convertTargetUrlHandler.getConvertTarget(bidContext, entry.getTargetUrl()),
					"UTF-8");
		} catch (UnsupportedEncodingException e) {
			LOGGER.warn("targetUrl 编码失败.", e);
		}

		// 添加扩展url
		String extend = convertTargetUrlHandler.convertExtendClickUrl(bidContext);

		return trackingService.buildClickQueryString2("2.0", NumberUtils.toInt(bidContext.getChannel(), BES_DEFAULT_CHANNEL), BES_DEFAULT_PLATFORM, 0,
				bidContext.getStrategyId(), bidContext.getCreativeId(), bidContext.getMaterialId(),
				bidContext.getGuid(), targetUrl, extend, bidContext.getOs());
	}

}
